package com.jingdong.api.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.Map;

/**
 * API结果模型
 *
 * @author 林生
 * @version 1.0.0
 */
public class ApiResult {
    
    /**
     * 是否成功
     */
    private boolean success;
    
    /**
     * 响应码
     */
    private int code;
    
    /**
     * 响应消息
     */
    private String message;
    
    /**
     * 响应数据
     */
    private Map<String, Object> data;
    
    /**
     * 请求ID
     */
    @JsonProperty("request_id")
    private String requestId;
    
    /**
     * 构造函数
     */
    public ApiResult() {
    }
    
    /**
     * 构造函数
     * 
     * @param success 是否成功
     * @param code 响应码
     * @param message 响应消息
     * @param data 响应数据
     * @param requestId 请求ID
     */
    public ApiResult(boolean success, int code, String message, Map<String, Object> data, String requestId) {
        this.success = success;
        this.code = code;
        this.message = message;
        this.data = data;
        this.requestId = requestId;
    }
    
    /**
     * 创建成功结果
     * 
     * @param data 响应数据
     * @return ApiResult
     */
    public static ApiResult success(Map<String, Object> data) {
        return new ApiResult(true, 0, "请求成功", data, "");
    }
    
    /**
     * 创建成功结果
     * 
     * @param data 响应数据
     * @param message 成功消息
     * @return ApiResult
     */
    public static ApiResult success(Map<String, Object> data, String message) {
        return new ApiResult(true, 0, message, data, "");
    }
    
    /**
     * 创建成功结果
     * 
     * @param data 响应数据
     * @param message 成功消息
     * @param requestId 请求ID
     * @return ApiResult
     */
    public static ApiResult success(Map<String, Object> data, String message, String requestId) {
        return new ApiResult(true, 0, message, data, requestId);
    }
    
    /**
     * 创建失败结果
     * 
     * @param code 错误码
     * @param message 错误消息
     * @return ApiResult
     */
    public static ApiResult error(int code, String message) {
        return new ApiResult(false, code, message, null, "");
    }
    
    /**
     * 创建失败结果
     * 
     * @param code 错误码
     * @param message 错误消息
     * @param data 响应数据
     * @return ApiResult
     */
    public static ApiResult error(int code, String message, Map<String, Object> data) {
        return new ApiResult(false, code, message, data, "");
    }
    
    /**
     * 创建失败结果
     * 
     * @param code 错误码
     * @param message 错误消息
     * @param data 响应数据
     * @param requestId 请求ID
     * @return ApiResult
     */
    public static ApiResult error(int code, String message, Map<String, Object> data, String requestId) {
        return new ApiResult(false, code, message, data, requestId);
    }
    
    /**
     * 从API响应创建结果
     * 
     * @param response API响应
     * @return ApiResult
     */
    @SuppressWarnings("unchecked")
    public static ApiResult fromResponse(Map<String, Object> response) {
        Integer code = (Integer) response.getOrDefault("code", -1);
        String message = (String) response.getOrDefault("message", "未知错误");
        Map<String, Object> data = (Map<String, Object>) response.get("data");
        String requestId = (String) response.getOrDefault("request_id", "");
        boolean success = code == 0;
        
        return new ApiResult(success, code, message, data, requestId);
    }
    
    /**
     * 转换为JSON字符串
     * 
     * @return JSON字符串
     */
    public String toJson() {
        try {
            ObjectMapper mapper = new ObjectMapper();
            return mapper.writeValueAsString(this);
        } catch (JsonProcessingException e) {
            return String.format("{\"success\":%b,\"code\":%d,\"message\":\"%s\"}", 
                    success, code, message);
        }
    }
    
    @Override
    public String toString() {
        return toJson();
    }
    
    // Getters and Setters
    public boolean isSuccess() {
        return success;
    }
    
    public void setSuccess(boolean success) {
        this.success = success;
    }
    
    public int getCode() {
        return code;
    }
    
    public void setCode(int code) {
        this.code = code;
    }
    
    public String getMessage() {
        return message;
    }
    
    public void setMessage(String message) {
        this.message = message;
    }
    
    public Map<String, Object> getData() {
        return data;
    }
    
    public void setData(Map<String, Object> data) {
        this.data = data;
    }
    
    public String getRequestId() {
        return requestId;
    }
    
    public void setRequestId(String requestId) {
        this.requestId = requestId;
    }
}
